using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;

namespace PoolSystem
{
    [System.Serializable]
    public class Pool
    {
        public GameObject Prefab => prefab;//lambda表达式
        [FormerlySerializedAs("_prefab")] [SerializeField]
        GameObject prefab;// 对象池的prefab
        private Queue<GameObject> _queue;
        [SerializeField]
        private int size = 1; // 对象池大小
        public int Size => size;
        public int RuntimeSize => _queue.Count;//运行时实际的对象池大小，也就是队列的大小

        private Transform _parent;//设置这个对象池的父物体

        /// <summary>
        /// 初始化对象池
        /// </summary>
        public void Initialize(Transform parent)
        {
            _queue = new Queue<GameObject>();
            _parent = parent;
            //将所有的预制体加入到队列中
            for (int i = 0; i < size; i++)
            {
                _queue.Enqueue(Copy());
            }
        }
        
        /// <summary>
        /// 生成备用对象
        /// 复制得到的都是prefab的复制体
        /// </summary>
        GameObject Copy()
        {
            var copy = GameObject.Instantiate(prefab, _parent);
            copy.SetActive(false);
            return copy;
        }

        /// <summary>
        /// 获取一个可用的对象
        /// </summary>
        /// <returns></returns>
        GameObject AvailableObject()
        {
            GameObject availableObject = null;

            if (_queue.Count > 0 && !_queue.Peek().activeSelf) //如果队列不为空，并且队列的第一个元素没有被激活，那么就直接用
            {
                availableObject = _queue.Dequeue();
            }
            else
            {
                availableObject = Copy();//如果队列为空，那么需要重新生成一个来用
            }
            //在返回可用的对象之前先将这个对象加入到队列中
            if (availableObject != null)
            {
                _queue.Enqueue(availableObject);
            }
            return availableObject;
        }

        /// <summary>
        /// 启用可用的对象
        /// </summary>
        /// <returns></returns>
        ///
        public GameObject PreparedObject()
        {
            GameObject preparedObject = AvailableObject();
            preparedObject.SetActive(true);
            
            return preparedObject;
        }
        public GameObject PreparedObject(Vector3 positon)
        {
            GameObject preparedObject = AvailableObject();
            preparedObject.transform.position = positon;
            preparedObject.SetActive(true);
            
            return preparedObject;
        }
        
        
        public GameObject PreparedObject(Vector3 positon, Quaternion rotation)
        {
            GameObject preparedObject = AvailableObject();
            preparedObject.transform.position = positon;
            preparedObject.transform.rotation = rotation;
            preparedObject.SetActive(true);
            
            return preparedObject;
        }
        
        public GameObject PreparedObject(Vector3 positon, Quaternion rotation, Vector3 localScale)
        {
            GameObject preparedObject = AvailableObject();
            preparedObject.transform.position = positon;
            preparedObject.transform.rotation = rotation;
            preparedObject.transform.localScale = localScale;
            preparedObject.SetActive(true);
            return preparedObject;
        }
        

        
    }
    
}
